package com.umeox.phone.ui;

import static com.umeox.moto.watch.themes.AppJob.EXTRA_JOB_TYPE;
import static com.umeox.moto.watch.themes.AppJob.JOB_TYPE_MISSED_CALL;
import static com.umeox.phone.util.Utils.saveLog;

import android.app.Activity;
import android.bluetooth.BluetoothHeadset;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
import android.provider.CallLog;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.signature.EmptySignature;
import com.bumptech.glide.util.Util;
import com.umeox.moto.common.log.Logger;
import com.umeox.moto.watch.themes.app.ThemeAppCompatActivity;
import com.umeox.moto.watch.themes.util.UToast;
import com.umeox.phone.R;
import com.umeox.phone.base.BaseApplication;
import com.umeox.phone.base.GlideApp;
import com.umeox.phone.util.CacheUtils;
import com.umeox.phone.util.Utils;
import com.umeox.watch.moto.dataservice.DataProvider;
import com.umeox.watch.moto.dataservice.constants.Constants;

import java.security.MessageDigest;

/**
 * 来电显示界面
 *
 * @author zl
 */
public class InCallUIActivity extends ThemeAppCompatActivity implements View.OnClickListener {
    /**
     * 来电号码extra
     */
    public static final String EXTRA_PHONE_NUM = "phoneNum";
    public static final String CALL_TYPE = "call_type";
    public static final String STATE_CALL_RINGTONE = "key_phone_state_Ringtone";

    /**
     * 挂断电话action
     */
    public static final String ACTION_END_CALL = "com.umeox.phone.ACTION_END_CALL";
    public static final String ACTION_LISTEN_CALL_END = "com.wherecom.intent.action.CALL_PHONE_END";
    public static final String ACTION_OUT_CALL_CONNECT = "com.umeox.phone.ACTION_OUT_CALL_CONNECT";
    public static final String ACTION_NETWORK_UNAVAILABLE = "com.wherecom.intent.inner.action.MOBILE_NETWORK_NOT_AVAILABLE";
    public static final String ACTION_CALL_STATE_CHANGE = "com.wherecom.intent.inner.action.ACTION_CALL_STATE_CHANGE";

    //时长计时器
    public Chronometer mDurationChronometer;

    private TextView mCallTypeTv;
    private TextView mMicrophoneIv;
    private ImageView mAnswerIv;
    private ImageView mHangupIv;
    private ImageView mVolumeIv;
    private ImageView mAvatar;

    private View mVolumeView;
    private com.umeox.moto.watch.themes.widget.TextView mNameTv;

    public static String phoneNum = "";
    public static String contactName = "";
    private int mCallType;
    public static final String TAG = "CallPhone";
    private AudioManager mAudioManager;
    private boolean mUserRefused;

    private CallPhoneReceiver mBluetoothReceiver;
    private int currentVolume;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

        setupData();
        initView();
        addListener();

        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_END_CALL);
        filter.addAction(ACTION_NETWORK_UNAVAILABLE);
        filter.addAction(ACTION_OUT_CALL_CONNECT);
        filter.addAction(ACTION_CALL_STATE_CHANGE);
        filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
        mBluetoothReceiver = new CallPhoneReceiver();
        registerReceiver(mBluetoothReceiver, filter);


    }


    private String getGlide4_SafeKey(String url) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            EmptySignature signature = EmptySignature.obtain();
            signature.updateDiskCacheKey(messageDigest);
            new GlideUrl(url).updateDiskCacheKey(messageDigest);
            String safeKey = Util.sha256BytesToHex(messageDigest.digest());
            return safeKey + ".0";
        } catch (Exception e) {
        }
        return null;
    }

    private void setupData() {
        mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);

        final int focus = mAudioManager.requestAudioFocus(null, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN);
        Log.d(TAG, "onCreate requestAudioFocus:" + focus);
        setContentView(R.layout.incallui_activity);
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "My:Tag");
        wakeLock.acquire(5000);
        mCallType = getIntent().getIntExtra(CALL_TYPE, 2);
        saveLog("onCreate requestAudioFocus:" + focus + " " + this);
        if (getIntent().hasExtra(EXTRA_PHONE_NUM)) {
            phoneNum = getIntent().getStringExtra(EXTRA_PHONE_NUM);
            contactName = Utils.getContactNameFromPhoneBook(getApplicationContext(), phoneNum);
        }
    }

    /**
     * 初始化界面
     */
    private void initView() {
        mDurationChronometer = findViewById(R.id.tvDuration);
        mNameTv = findViewById(R.id.name_tv);
        mMicrophoneIv = findViewById(R.id.iv_microphone);
        mCallTypeTv = findViewById(R.id.tvCallType);
        mVolumeIv = findViewById(R.id.iv_volume);
        mAnswerIv = findViewById(R.id.ivAnswer);
        mHangupIv = findViewById(R.id.ivHangup);
        mAvatar = findViewById(R.id.avatar);
        mVolumeView = findViewById(R.id.volume_fl);

        String contactPhotoUrl = DataProvider.getContactPhoto(phoneNum);
        if (TextUtils.isEmpty(contactPhotoUrl)) {
            int rawContactId = Utils.getRawContactId(this, phoneNum);
            contactPhotoUrl = DataProvider.getContactUrlByRawContactId(rawContactId);
            Logger.e(TAG, "rawContactId = " + rawContactId + ",contactPhotoUrl=" + contactPhotoUrl);
        }

        GlideApp.with(mContext)
                .load(contactPhotoUrl)
                .placeholder((R.drawable.default_bg))
                .error(R.drawable.default_bg)
                .apply(RequestOptions.bitmapTransform(new CircleCrop()))
                .into(mAvatar);

        mDurationChronometer.setVisibility(View.GONE);

        switch (mCallType) {
            case 1:
                mVolumeView.setVisibility(View.GONE);
                mVolumeIv.setVisibility(View.GONE);
                mNameTv.setText(!TextUtils.isEmpty(contactName) ? contactName : phoneNum);
                mCallTypeTv.setText(getResources().getString(R.string.calling));
//                setTextDrawableLeft(mCallTypeTv, R.drawable.contact_voice);
                mAnswerIv.setVisibility(View.GONE);
                mHangupIv.setVisibility(View.VISIBLE);

                break;
            case 2:
                mVolumeView.setVisibility(View.VISIBLE);
                mVolumeIv.setVisibility(View.GONE);
                mNameTv.setText(!TextUtils.isEmpty(contactName) ? contactName : phoneNum);
                mCallTypeTv.setText(getResources().getString(R.string.incoming_call));
//                setTextDrawableLeft(mCallTypeTv, R.drawable.contact_voice);
                mAnswerIv.setVisibility(View.VISIBLE);
                mHangupIv.setVisibility(View.VISIBLE);

                break;
        }
    }


    /**
     * 添加监听器
     */
    private void addListener() {
        getContentResolver().registerContentObserver(CallLog.Calls.CONTENT_URI, true, mCallLogObserver);
        mHangupIv.setOnClickListener(this);
        mAnswerIv.setOnClickListener(this);
        mVolumeIv.setOnClickListener(this);
        mMicrophoneIv.setOnClickListener(this);

    }

    private ContentObserver mCallLogObserver = new ContentObserver(new Handler()) {
        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            Log.d(TAG, "onChange: " + this);
            if (mUserRefused) {
                Utils.updateCallLog(getApplicationContext());
            } else {
                setupAppJobService();
            }

            boolean isListen = CacheUtils.isCallMonitoring(mContext);
            boolean isCalling = CacheUtils.isCallStateCalling(mContext);
            saveLog("ContentObserver " + "isListen: " + isListen + " isCalling: " + isCalling);
            if (isListen || isCalling) {
                return;
            }
            saveLog("ContentObserver " + "mCallLogObserver finish");
            finish();
        }
    };

    /**
     * 查询未接来电数量
     */
    public void setupAppJobService() {
        Intent intent = new Intent();
        intent.setAction("com.umeox.watch.launcher.APP_JOB_SERVICE");
        intent.setPackage("com.umeox.watch.moto.launcher");
        intent.putExtra(EXTRA_JOB_TYPE, JOB_TYPE_MISSED_CALL);
        startService(intent);
    }

    //    Intent.ACTION_MEDIA_BUTTON
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PLAY) {
            if (Utils.isRinging(mContext)) {
                updateUI();
                return true;
            }
        }
        return super.dispatchKeyEvent(event);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return keyCode == KeyEvent.KEYCODE_BACK;
    }

    protected synchronized void updateUI() {
        Log.d(TAG, "updateUI: ");
        CacheUtils.setCallStateCalling(mContext, true);
        Utils.answerCall(InCallUIActivity.this);
        showChronometer();
        mAnswerIv.setVisibility(View.GONE);
    }

    private void showChronometer() {
        Log.d(TAG, "showChronometer: ");
        mCallTypeTv.setVisibility(View.GONE);
        mVolumeIv.setVisibility(View.VISIBLE);
        mVolumeView.setVisibility(View.VISIBLE);
//        mMicrophoneIv.setVisibility(View.VISIBLE);
        mDurationChronometer.setVisibility(View.VISIBLE);
        mDurationChronometer.setBase(SystemClock.elapsedRealtime());
        mDurationChronometer.start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        saveLog("onDestroy " + this);
        Log.d(TAG, "onDestroy: " + this);
        Utils.setMicrophoneMute(this, false);
        CacheUtils.setCallStateCalling(mContext, false);
        mAudioManager.abandonAudioFocus(null);
        for (Activity activity : BaseApplication.mList) {
            activity.finish();
        }

        if (mBluetoothReceiver != null) {
            unregisterReceiver(mBluetoothReceiver);
        }

        getContentResolver().unregisterContentObserver(mCallLogObserver);
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }


    /**
     * @param cmt Chronometer控件
     * @return 小时+分钟+秒数  的所有秒数
     */
    public static int getChronometerSeconds(Chronometer cmt) {
        int totalss = 0;
        String string = cmt.getText().toString();
        if (string.length() == 7) {

            String[] split = string.split(":");
            String string2 = split[0];
            int hour = Integer.parseInt(string2);
            int Hours = hour * 3600;
            String string3 = split[1];
            int min = Integer.parseInt(string3);
            int Mins = min * 60;
            int SS = Integer.parseInt(split[2]);
            totalss = Hours + Mins + SS;
            return totalss;
        } else if (string.length() == 5) {
            String[] split = string.split(":");
            String string3 = split[0];
            int min = Integer.parseInt(string3);
            int Mins = min * 60;
            int SS = Integer.parseInt(split[1]);
            totalss = Mins + SS;
            return totalss;
        }
        return totalss;
    }

    public static Uri getUriFromDrawableRes(Context context, int id) {
        Resources resources = context.getResources();
        String path = ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
                + resources.getResourcePackageName(id) + "/"
                + resources.getResourceTypeName(id) + "/"
                + resources.getResourceEntryName(id);
        return Uri.parse(path);
    }

    private void setTextDrawableLeft(TextView textView, int resId) {
        Drawable drawableLeft = getResources().getDrawable(resId);
        textView.setCompoundDrawablesRelativeWithIntrinsicBounds(drawableLeft, null, null, null);
    }


    @Override
    public void onClick(View v) {
        final int id = v.getId();
        switch (id) {
            case R.id.ivHangup:
                mUserRefused = true;
                Utils.endCall(mContext);
                mDurationChronometer.stop();
                CacheUtils.setCallStateCalling(this, false);
                moveTaskToBack(false);
                break;
            case R.id.iv_volume:
                Intent intent = new Intent(this, VolumeActivity.class);
                startActivity(intent);
                break;

            case R.id.iv_microphone:
                mMicrophoneIv.setSelected(!mMicrophoneIv.isSelected());
                Utils.setMicrophoneMute(this, mMicrophoneIv.isSelected());
                break;
            case R.id.ivAnswer:
                updateUI();
                break;
        }
    }

    public class CallPhoneReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {


            final String action = intent.getAction();
            if (action == null) {
                return;
            }
            Log.d(TAG, "CallPhoneReceiver$onReceive: " + action);
            switch (action) {
                case ACTION_END_CALL:
                    sendCallDuration(intent);
                    break;
                case ACTION_NETWORK_UNAVAILABLE:
                    try {
                        UToast.showCustomToast(mContext, getResources().getString(R.string.mobile_network_error), Toast.LENGTH_LONG);
                    } catch (Exception ignored) {

                    }
                    InCallUIActivity.this.finish();
                    break;
                case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED:
                    bluetoothA2dpChanged(intent);
                    break;
                case ACTION_OUT_CALL_CONNECT:
                    if (CacheUtils.isCallStateCalling(mContext)) return;
                    CacheUtils.setCallStateCalling(mContext, true);
                    showChronometer();
                    if(!Utils.isHeadsetPluggedIn(mContext)){
                        Utils.openSpeaker(mContext);
                    }

                    break;
                case ACTION_CALL_STATE_CHANGE:
                    int state = intent.getIntExtra("state", 0);
                    if (CacheUtils.isCallStateCalling(mContext)) return;
                    if (state == TelephonyManager.CALL_STATE_OFFHOOK && mCallType != 1) {
                        updateUI();
                    }
                    break;
            }

        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (RESULT_OK == resultCode && data != null) {
            int intExtra = data.getIntExtra(VolumeActivity.KEY_VOLUME_RESULT, 0);
            Log.d(TAG, "onActivityResult: " + intExtra);
            mVolumeIv.setSelected(intExtra <= 0);
        }
    }

    private void bluetoothA2dpChanged(Intent intent) {
        int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, -1);

        switch (state) {
            case BluetoothHeadset.STATE_CONNECTED:
                Utils.closeSpeaker(mContext);
                break;

            case BluetoothHeadset.STATE_DISCONNECTED:
                Utils.openSpeaker(mContext);
                break;
        }
    }

    private void sendCallDuration(Intent intent) {
        CacheUtils.setCallStateCalling(this, false);
        mDurationChronometer.stop();
        int callType = intent.getIntExtra("callType", 0);
        long endCallTime = intent.getLongExtra("endCallTime", 0);
        int duration = getChronometerSeconds(mDurationChronometer);
        if (duration > 0) {
            Intent intent1 = new Intent();
            intent1.setAction(Constants.ACTION_HANG_UP);
            intent1.putExtra(Constants.EXTRA_CALL_DURATION, duration);
            intent1.putExtra(Constants.EXTRA_PHONE_NUMBER, phoneNum);
            intent1.putExtra(Constants.EXTRA_CONTACT_NAME, contactName);
            intent1.putExtra(Constants.EXTRA_CALL_TYPE, mCallType - 1);
            intent1.putExtra(Constants.EXTRA_OFFHOOK_TIME, endCallTime);
            sendBroadcast(intent1);
        }
        if(PhoneNumberUtils.isEmergencyNumber(phoneNum)){
            finish();
            return;
        }
        moveTaskToBack(false);
    }

    @Override
    protected void registerUnbindAndDisableReceiver(boolean register) {
    }
}
